package com.yxq.mdt.app.net;


import android.util.Log;

import androidx.annotation.NonNull;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.ihsanbal.logging.Level;
import com.ihsanbal.logging.LoggingInterceptor;
import com.orhanobut.hawk.Hawk;
import com.yxq.mdt.app.BuildConfig;
import com.yxq.mdt.app.constant.Constant;
import com.yxq.mdt.app.constant.SPKey;
import com.yxq.mdt.app.modules.login.bean.UserBean;
import com.yxq.mdt.app.modules.personal.bean.MainPersonTokenBean;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.platform.Platform;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * @描述 Retrofit+OkHttp3实现网络请求框架
 * @作者 yd
 * @创建日期 2019/8/27 0027 15:06
 */
public class RetrofitFactory {

    private static final int TIME_OUT_TIME = 120;
    private static final CacheControl FORCE_CACHE1 = new CacheControl.Builder().onlyIfCached()
            .maxStale(60 * 60 * 24 * 7, TimeUnit.SECONDS)
            .build();


    /**
     * 缓存机制
     * 在响应请求之后在 data/data/<包名>/cache 下建立一个response 文件夹，保持缓存数据。
     * 这样我们就可以在请求的时候，如果判断到没有网络，自动读取缓存的数据。
     * 同样这也可以实现，在我们没有网络的情况下，重新打开App可以浏览的之前显示过的内容。
     * 也就是：判断网络，有网络，则从网络获取，并保存到缓存中，无网络，则从缓存中获取。
     * https://werb.github.io/2016/07/29/%E4%BD%BF%E7%94%A8Retrofit2+OkHttp3%E5%AE%9E%E7%8E%B0%E7%BC%93%E5%AD%98%E5%A4%84%E7%90%86/
     */
    private static final Interceptor cacheControlInterceptor = chain -> {
        Request request = chain.request();
        if (!NetworkUtils.isConnected()) {
            request = request.newBuilder().cacheControl(FORCE_CACHE1).build();
        }

        Response originalResponse = chain.proceed(request);
        if (NetworkUtils.isConnected()) {
            // 有网络时 设置缓存为默认值
            String cacheControl = request.cacheControl().toString();
            return originalResponse.newBuilder()
                    .header("Cache-Control", cacheControl)
                    .removeHeader("Pragma") // 清除头信息，因为服务器如果不支持，会返回一些干扰信息，不清除下面无法生效
                    .build();
        } else {
            // 无网络时 设置超时为1周
            int maxStale = 60 * 60 * 24 * 7;
            return originalResponse.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .removeHeader("Pragma")
                    .build();
        }
    };
    /**
     * header
     */
    private static final Interceptor headerInterceptor = chain -> {
        UserBean userBean = Hawk.get(SPKey.SP_KEY_USER_INFO);
        MainPersonTokenBean mainPersonTokenBean = Hawk.get(SPKey.SP_KEY_USER_INFO_TOKEN);
        Request request = chain.request().newBuilder()
//                .addHeader(ApiConfig.REQ_APP_VERSION, AppUtils.getAppVersionName())
//                .addHeader(ApiConfig.REQ_DEVICE_TYPE, ApiConfig.DEVICE_TYPE_ANDROID)
//                .addHeader(ApiConfig.REQ_DEVICE_ID, DeviceUtils.getAndroidID())
//                .addHeader(ApiConfig.REQ_APP_CHANNEL, "appChannel")
//                .addHeader(ApiConfig.REQ_CHANNEL_KEY, "appKey")
                .addHeader(ApiConfig.REQ_ACCESS_TOKEN, userBean != null ? userBean.getAccess_token() : "")
                .addHeader(ApiConfig.REQ_JAVA_TOKEN, mainPersonTokenBean != null ? mainPersonTokenBean.getToken() : "")
                .build();

        return chain.proceed(request);
    };

    private volatile static Retrofit retrofit;
    private volatile static Retrofit mJavaRetrofit;
    private volatile static Retrofit mPMRetrofit;
    private volatile static Retrofit mJavaFromRetrofit;

    public static OkHttpClient.Builder initInterceptor(OkHttpClient.Builder builder) {
        builder.addInterceptor(new LoggingInterceptor.Builder()
                .loggable(true)
                .setLevel(Level.BASIC)
                .log(Platform.INFO)
                .request("Request")
                .response("Response")
                .build());
        return builder;
    }

    @NonNull
    public static Retrofit getRetrofit() {
        if (retrofit == null) {
            synchronized (RetrofitFactory.class) {
                if (retrofit == null) {
                    OkHttpClient.Builder builder = new OkHttpClient.Builder()
                            .addInterceptor(headerInterceptor)
//                            .addNetworkInterceptor(cacheControlInterceptor)
                            .connectTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .readTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .writeTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .retryOnConnectionFailure(true);

                    builder.addInterceptor(InterceptorUtil.phpCommonParamInterceptor());

                    // Log 拦截器
                    if (BuildConfig.DEBUG) {
                        builder = initInterceptor(builder);
                    }

                    retrofit = new Retrofit.Builder()
                            .baseUrl(API.HOST_PHP)
                            .client(builder.build())
                            .addConverterFactory(FastJsonConverterFactory.create())
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .build();
                }
            }
        }
        return retrofit;
    }

    @NonNull
    public static Retrofit getJavaRetrofit() {
        if (mJavaRetrofit == null) {
            synchronized (RetrofitFactory.class) {
                if (mJavaRetrofit == null) {
                    OkHttpClient.Builder builder = new OkHttpClient.Builder()
                            .addInterceptor(headerInterceptor)
//                            .addNetworkInterceptor(cacheControlInterceptor)
                            .connectTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .readTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .writeTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)

                            .retryOnConnectionFailure(true);

                    builder.addInterceptor(InterceptorUtil.javaCommonParamInterceptor());

                    // Log 拦截器
                    if (BuildConfig.DEBUG) {
                        builder = initInterceptor(builder);
                    }

                    mJavaRetrofit = new Retrofit.Builder()
                            .baseUrl(API.HOST_JAVA)
                            .client(builder.build())
                            .addConverterFactory(FastJsonConverterFactory.create())
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .build();
                }
            }
        }
        return mJavaRetrofit;
    }

    @NonNull
    public static Retrofit getPMRetrofit() {
        if (mPMRetrofit == null) {
            synchronized (RetrofitFactory.class) {
                if (mPMRetrofit == null) {
                    OkHttpClient.Builder builder = new OkHttpClient.Builder()
                            .addInterceptor(headerInterceptor)
//                            .addNetworkInterceptor(cacheControlInterceptor)
                            .connectTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .readTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                            .writeTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)

                            .retryOnConnectionFailure(true);

                    builder.addInterceptor(InterceptorUtil.javaCommonParamInterceptor());

                    // Log 拦截器
                    if (BuildConfig.DEBUG) {
                        builder = initInterceptor(builder);
                    }

                    mPMRetrofit = new Retrofit.Builder()
                            .baseUrl(API.HOST_PM)
                            .client(builder.build())
                            .addConverterFactory(FastJsonConverterFactory.create())
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .build();
                }
            }
        }
        return mPMRetrofit;
    }

    @NonNull
    public static Retrofit getJavaFormRetrofit() {

        synchronized (RetrofitFactory.class) {
            if (mJavaFromRetrofit == null) {
                OkHttpClient.Builder builder = new OkHttpClient.Builder()
                        .addInterceptor(headerInterceptor)
//                            .addNetworkInterceptor(cacheControlInterceptor)
                        .connectTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                        .readTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                        .writeTimeout(TIME_OUT_TIME, TimeUnit.SECONDS)
                        .retryOnConnectionFailure(true);

//                    builder.addInterceptor(InterceptorUtil.javaCommonParamInterceptor());

                // Log 拦截器
                if (BuildConfig.DEBUG) {
                    builder = initInterceptor(builder);
                }

                mJavaFromRetrofit = new Retrofit.Builder()
                        .baseUrl(API.HOST_JAVA)
                        .client(builder.build())
                        .addConverterFactory(FastJsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .build();
            }
        }
        return mJavaFromRetrofit;
    }
}
